package com.mangabiz.market.entities;

// Start of user code for imports
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Cascade;


// End of user code for imports

@Entity
public class Category implements Serializable {


	/**
	 * serialVersionUID is used for serialization.
	 */
	private static final long serialVersionUID = 1L;


	/**
	 * Constant representing the name of the automatic primary key field.
	 */
	public static final String PROP_ID = "id";


	/**
	 * Constant representing the name of the field name.
	 */
	public static final String PROP_NAME = "name";


	/**
	 * Constant representing the name of the field product.
	 */
	public static final String PROP_PRODUCT = "product";


	/**
	 * Automatic primary key.
	 */
	protected Long id;


	/**
	 * Field name.
	 */
	protected String name;


	/**
	 * Field product.
	 */
	protected Set<Product> product;


	protected Category parentCategory;


	protected Set<Category> subCategories;


	/**
	 * Default constructor.
	 */
	public Category() {
		super();
		product = new HashSet<Product>();
	}


	/**
	 * Returns the identifier.
	 * 
	 * @return Returns id.
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}


	/**
	 * Sets a value to parameter Id.
	 * 
	 * @param someId
	 *            Value of the identifier.
	 */
	public void setId(final Long someId) {
		id = someId;
	}


	/**
	 * Constructor with all parameters initialized.
	 * 
	 * @param someName
	 *            Warning, no comment in the model.
	 * @param someProduct
	 *            Warning, no comment in the model.
	 */
	public Category(String someName, Set<Product> someProduct) {
		name = someName;
		product = someProduct;
	}


	/**
	 * Returns name.
	 * 
	 * @return Warning, no comment in the model.
	 */
	@Basic(optional = false)
	@Column(nullable = false, length = 255)
	public String getName() {
		return name;
	}


	/**
	 * Sets a value to parameter name.
	 * 
	 * @param someName
	 *            Warning, no comment in the model.
	 */
	public void setName(final String someName) {
		name = someName;
	}


	/**
	 * Returns product.
	 * 
	 * @return Warning, no comment in the model.
	 */
	@OneToMany(mappedBy = "category")
	public Set<Product> getProduct() {
		return product;
	}


	/**
	 * Sets a value to parameter product.
	 * 
	 * @param someProduct
	 *            Warning, no comment in the model.
	 */
	public void setProduct(final Set<Product> someProduct) {
		product = someProduct;
	}


	/**
	 * Adds a product to the product Collection. Birectionnal association : add
	 * the current instance to the given product parameter.
	 * 
	 * @param productElt
	 *            Element to add
	 */
	public void addProduct(final Product productElt) {
		product.add(productElt);
		productElt.setCategory(this);
	}


	/**
	 * Removes a product from the product Collection. Birectionnal association :
	 * remove the current instance from the given product parameter.
	 * 
	 * @param productElt
	 *            Element to remove
	 */
	public void removeProduct(final Product productElt) {
		product.remove(productElt);
		productElt.setCategory(null);
	}


	/**
	 * @return the parentCategory
	 */
	@ManyToOne(optional = true)
	public Category getParentCategory() {
		return parentCategory;
	}


	/**
	 * @param parentCategory
	 *            the parentCategory to set
	 */
	public void setParentCategory(Category parentCategory) {
		this.parentCategory = parentCategory;
	}


	/**
	 * @return the subCategories
	 */
	@OneToMany(mappedBy = "parentCategory", fetch = FetchType.LAZY)
	@Cascade(value = { org.hibernate.annotations.CascadeType.ALL })
	public Set<Category> getSubCategories() {
		return subCategories;
	}


	/**
	 * @param subCategories
	 *            the subCategories to set
	 */
	protected void setSubCategories(Set<Category> subCategories) {
		this.subCategories = subCategories;
	}


	/**
	 * Equality test based on attributes values.
	 * 
	 * @param other
	 *            Value to compare
	 * @return Returns true if and only if given object is an instance of
	 *         Category and the given object has the same PK as this if the PK
	 *         is not null or their fields are equal.
	 */
	@Override
	public boolean equals(final Object other) {
		// Start of user code for equals
		if (this == other) {
			return true;
		}
		if (!(other instanceof Category)) {
			return false;
		}
		final Category castedOther = (Category) other;
		if (id != null && castedOther.getId() != null) {
			return id.equals(castedOther.getId());
		}
		if ((name == null && castedOther.getName() != null)
				|| (name != null && !name.equals(castedOther.getName()))) {
			return false;
		}
		if ((product == null && castedOther.getProduct() != null)
				|| (product != null && !product
						.equals(castedOther.getProduct()))) {
			return false;
		}
		return true;
		// End of user code for equals
	}


	/**
	 * HashTable code based on attributes hashcodes.
	 * 
	 * @return Returns hash value
	 */
	@Override
	public int hashCode() {
		// Start of user code for hashCode
		int result = 0;
		if (id != null) {
			result = id.hashCode();
		} else {
			if (name != null) {
				result = 29 * result + name.hashCode();
			}
		}
		return result;
		// End of user code for hashCode
	}

	// Start of user code for private methods
	// TODO Remove this line and add your private methods here
	// End of user code for private methods

}
